【PHP】switch文 - 条件分岐 / 変数の値による処理の分岐

【PHP】switch文 - 条件分岐 / 変数の値による処理の分岐

PHPプログラミングで条件分岐する方法の1つにswitch文があります。

ここでは、switch文について解説します。

検証環境

switch文

switch文は“条件分岐を実現する構文”です。

変数の値に応じた条件分岐のために使用します。

基本構文

switch( 変数 ) {
    case 条件値1 :
        // 分岐処理1...
    case 条件値2 :
        // 分岐処理2...
    default :
        // 必ず実行する処理
}

基本構文を分解して解説します。

先ず、switch(変数){}はswitch文の基本となる構造です。

switch( 変数 ) {
    
}

変数の部分に条件に使う変数を記述します。

次に分岐処理はcase 条件値 :を使います。

switch( 変数 ) {
___ih_diff_start
+    case 条件値 :
+        // 分岐処理...
___ih_diff_end
}

条件値の部分に定義した値と変数の値が等しい場合に分岐処理を実行します。

複数の分岐処理は同様にcase 条件値 :を追加します。

switch( 変数 ) {
    case 条件値1 :
        // 分岐処理1...
___ih_diff_start
+    case 条件値2 :
+        // 分岐処理2...
___ih_diff_end
}

default :は変数の値に関わらず、必ず実行する処理です。

switch( 変数 ) {
    case 条件値1 :
        // 分岐処理1...
    case 条件値2 :
        // 分岐処理2...
___ih_diff_start
+    default :
+        // 必ず実行する処理
___ih_diff_end
}

以上がswitch文の基本構文の構造ですが、一般的にはbreakを合わせて使います。

breakは一番近いブロック(波括弧{})の処理を中断するキーワードです。

switch文は条件分岐したcaseから下の処理を全て実行するため、例えば、上記構文の1個目のcaseで条件分岐した場合、2個目のcaseに関わらず、3・5・7行目の処理が実行されます。

そのため、各caseの処理の最後にbreakを記述し、caseごとに処理を完結させます。

switch( 変数 ) {
    case 条件値1 :
        // 分岐処理1...
___ih_diff_start
+        break;
___ih_diff_end
    case 条件値2 :
        // 分岐処理2...
___ih_diff_start
+        break;
___ih_diff_end
    default :
        // 必ず実行する処理
}

defaultはそれ以降に分岐処理がないため、breakは必要ありません。

このようにbreakを合わせることで、各caseはif文/elseif文のように使用でき、defaultはいずれのcaseにも分岐しない場合のみ実行されるのでelse文のように使うことができます。

サンプル

<?php

$num = 3;

switch( $num ) {
    case 1 :
        echo '1個目のcaseです。';
        break;
    case 2 :
        echo '2個目のcaseです。';
        break;
    case 3 :
        echo '3個目のcaseです。';
        break;
    default :
        echo 'defaultです。';
}

?>
$ php sample1.php
3個目のcaseです。

$numの値は3のため、3個目のcaseの条件値に一致します。

そのため、13行目を実行した後、14行目のbreakにより、switchの処理が中断されました。

また、条件値は最終的には値であれば良いため、式で記述できます。

<?php

$num = 3;

___ih_hl_start
$condition = 1;
___ih_hl_end

switch( $num ) {
___ih_hl_start
    case $condition + 1 :
___ih_hl_end
        echo '1個目のcaseです。';
        break;
___ih_hl_start
    case $condition + 2 :
___ih_hl_end
        echo '2個目のcaseです。';
        break;
___ih_hl_start
    case $condition + 3 :
___ih_hl_end
        echo '3個目のcaseです。';
        break;
    default :
        echo 'defaultです。';
}

?>
$ php sample2.php
2個目のcaseです。

breakの有無

breakの有無による動作の違いを確認します。

上記サンプルのsample2.phpからbreakを削除したソースコードを実行します。

<?php
 
$num = 3;
 
$condition = 1;
 
switch( $num ) {
    case $condition + 1 :
        echo '1個目のcaseです。';
    case $condition + 2 :
        echo '2個目のcaseです。';
    case $condition + 3 :
        echo '3個目のcaseです。';
    default :
        echo 'defaultです。';
}
 
?>
$ php sample3.php
2個目のcaseです。3個目のcaseです。defaultです。

先ほどとは変わり、出力結果に3個目のcaseです。defaultです。が増えました。

これはbreakがないことによって、switchの処理が中断されず、3個目のcasedefaultの分岐処理が実行されたことによる出力です。

この特性を活かしたコードを書くこともできますが、breakを忘れた場合、不具合等の原因になりますので注意しましょう。

if文とswitch文

if文とswitch文は条件分岐という同じ役割を持ちます。

一般的な条件分岐ではif文が使われますが、“1つの変数の値に応じた分岐処理”の場合はswitch文が適している場合があります。

サンプルのsample1.phpをif文で書き換えると次のようになります。

<?php
 
$num = 3;

if( $num == 1 ) {
    echo '1個目のcaseです。';
} else if( $num == 2 ) {
    echo '2個目のcaseです。';
} else if( $num == 3 ) {
    echo '3個目のcaseです。';
} else {
    echo 'defaultです。';
}
 
?>
$ php sample4.php
3個目のcaseです。

全ての条件式に$num ==があり冗長的で、$numの変数名に変更がある場合、全ての条件式も修正が必要です。

また、コードを読む時、if文の条件式は自由度が高いため、1つ1つその条件の内容を確認する必要があります。

switch文は簡潔で変数名の変更などの対応も最小限です。

コードを読む時も変数の値が“何か”なので、比較的理解しやすい傾向にあります。

注意点

switch文の条件値に条件式を記述できますが、これは意図しない動作を生む可能性があります。

<?php

$num = 0;

switch( $num ) {
    case $num >= 0 :
        echo '1個目のcaseです。';
        break;
    case $num >= 10 :
        echo '2個目のcaseです。';
        break;
    case $num >= 20 :
        echo '3個目のcaseです。';
        break;
    default :
        echo 'defaultです。';
}

?>
$ php sample5.php
2個目のcaseです

このコードは一見、1個目のcaseが実行されるように見えますが、実際には2個目が実行されます。

switch文は変数の値と条件値が等しいかどうかを判定します。

そのため、1個目のcase$num >= 0trueですが、$num == truefalseです。

そして、2個目のcase$num >= 10falseですが、$num == falsetrueになります。

$num == falseは暗黙のキャスト(自動型変換)により同じ値とみなされるようです。

switch文はこの点を注意して使用する必要があります。